docs: HTTP gateway extensions how-to and zstd config flags#85
Conversation
Add a new how-to page covering core's RegisterServeMuxOption and
RegisterHTTPMarshaler hooks. Page contents:
- Overview of the two functions and the init-only constraint.
- Ordering rules table (last-write-wins vs additive options) with the
WithIncomingHeaderMatcher caveat.
- Worked recipes:
- MessagePack marshaler via shamaton/msgpack with a protojson bridge
for proto WKT correctness.
- Tuning the default runtime.JSONPb (EmitUnpopulated, UseProtoNames,
Indent) by registering for runtime.MIMEWildcard.
- Per-route middleware via runtime.WithMiddlewares (request size limit
example).
- Custom error handler via runtime.WithErrorHandler returning a
vendor-specific error envelope.
- "When to reach for these hooks" guidance pointing back at
Interceptors for gRPC-side concerns.
Also:
- howto/index.md — new index row linking to the page.
- config-reference.md — DISABLE_ZSTD_COMPRESSION and PREFER_ZSTD rows
documenting the new core flags.
- tests/navigation.spec.ts — add /howto/gateway-extensions/ to the
Playwright howtoPages list so CI asserts the page loads.
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughAdds a new "HTTP Gateway Extensions" how-to documenting init-time grpc-gateway hooks and example recipes, adds two zstd-related HTTP gateway config flags to the configuration reference, updates the how-to index, and extends site tests to include the new page. ChangesHTTP Gateway Extensions + Config & Tests
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Review rate limit: 0/1 reviews remaining, refill in 60 minutes.Comment |
There was a problem hiding this comment.
Pull request overview
Adds new documentation and navigation coverage for extending ColdBrew’s grpc-gateway HTTP layer, and documents new HTTP compression-related config flags.
Changes:
- New How-To page documenting
RegisterServeMuxOption/RegisterHTTPMarshalerhooks with ordering rules and recipes. - Adds the new How-To link to the How-To index and ensures Playwright CI checks the page loads.
- Documents
DISABLE_ZSTD_COMPRESSIONandPREFER_ZSTDin the configuration reference.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
tests/navigation.spec.ts |
Adds the new How-To URL to the Playwright “howto page loads” list. |
howto/index.md |
Adds a row linking to the new “HTTP Gateway Extensions” page. |
howto/gateway-extensions.md |
Introduces a new How-To page describing HTTP gateway extension hooks and recipes. |
config-reference.md |
Documents two new HTTP gateway compression flags (zstd-specific controls). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Addresses Copilot review feedback on PR #85. Match the established quickstart pattern (cb := core.New(cfg) followed by cb.Run()) instead of pointing readers at a non-existent core.Run() free function.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Replace 'a package init' with 'a package-level init() function' since package init isn't a Go construct. - Add a warning callout that the msgpack NewDecoder reads the full request body via io.ReadAll; pair with http.MaxBytesReader middleware (which the per-route middleware recipe already demonstrates). - Drop the 'coldbrew' import alias and use 'core' consistently across all four PreStart snippets, matching the convention in quickstart.md and other how-to pages. - Remove the unused [ColdBrew cookiecutter] reference link.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@howto/gateway-extensions.md`:
- Around line 138-147: The import blocks in the PreStart examples are missing
the context package needed for the PreStart function signature; update the
import lists that accompany the PreStart snippets to include "context" so that
functions referencing context.Context (e.g., the PreStart method on Service)
compile—specifically add "context" to the import block shown above the PreStart
function and to the other identical snippets that reference context.Context.
- Around line 225-236: envelopeErrorHandler currently ignores the error returned
by m.Marshal which can produce an empty/invalid response; update the function
(envelopeErrorHandler) to check the error from m.Marshal(payload) and handle it:
if marshal succeeds, write the body as before; if marshal fails, log the marshal
error and write a safe fallback response (e.g., a minimal JSON/error string or
use http.Error) and ensure the HTTP status
(runtime.HTTPStatusFromCode(s.Code())) and Content-Type are still set
appropriately; reference m.Marshal, payload, w.Write, and
runtime.HTTPStatusFromCode when making the change.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 4cd815b2-6767-4ce8-a582-4ee632cd8ef1
📒 Files selected for processing (4)
config-reference.mdhowto/gateway-extensions.mdhowto/index.mdtests/navigation.spec.ts
- Add missing 'context' import to the msgpack, JSONPb, and middleware PreStart snippets so they compile as pasted. - Restructure envelopeErrorHandler to marshal the payload first and fall back via http.Error on marshal failure, before writing Content-Type or the status code. The previous version discarded the marshal error and could leave the client with status set but an empty body.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Rename 'Recipe: Per-route middleware' to 'Recipe: Gateway middleware'. runtime.WithMiddlewares is mux-wide, not route-scoped; the old heading contradicted the body. Update the cross-reference link from the msgpack callout to match. - Rewrite the JSONPb intro to clarify that the wildcard registration only overrides the *fallback* marshaler. Add a note that callers who bind application/json explicitly (e.g. USE_JSON_BUILTIN_MARSHALLER=true) need to register the tuned JSONPb for that concrete MIME too. - Add a warning callout under the error-handler recipe noting that the map[string]any envelope only works for JSON-shaped marshalers. Proto-only marshalers (application/proto, application/protobuf) need a proto.Message such as status.Convert(err).Proto() or a custom generated proto envelope.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Move the gateway-extensions row to the bottom of the howto index table to match its nav_order (20), keeping the index in sync with the sidebar order. - Add /howto/local-dev/ to the Playwright howtoPages list. It's been linked from howto/index.md but missing from the smoke suite.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| func RegisterHTTPMarshaler(mime string, m runtime.Marshaler) | ||
| ``` | ||
|
|
||
| Use them to add custom marshalers (MessagePack, CBOR, vendor-specific JSON), tune the default protojson marshaler, register per-route middleware, install a custom error handler, or wire forward-response hooks — anything `runtime.ServeMuxOption` lets you do. |
There was a problem hiding this comment.
Fixed in f5944a1 — Overview now reads "register gateway middleware" to match the recipe heading and the body's mux-wide framing.
| ``` | ||
|
|
||
| {: .warning } | ||
| This snippet marshals a `map[string]any` envelope. JSON-shaped marshalers (`runtime.JSONPb`, `runtime.JSONBuiltin`, the JSON-bridged msgpack recipe above) accept it, but proto-only marshalers (`application/proto`, `application/protobuf`) require a `proto.Message` and would hit the `http.Error` fallback path. For a portable envelope, marshal `status.Convert(err).Proto()` (a `*google.golang.org/genproto/googleapis/rpc/status.Status` that implements `proto.Message`) instead of a freeform map — or define your own envelope as a generated proto. |
There was a problem hiding this comment.
Caught in f5944a1. The callout now only lists runtime.JSONPb and runtime.JSONBuiltin as accepting arbitrary Go values; the MessagePack recipe and runtime.ProtoMarshaller are explicitly grouped with the marshalers that would reject map[string]any and fall through to http.Error.
| "/howto/local-dev/", | ||
| "/howto/gateway-extensions/", |
There was a problem hiding this comment.
Done in f5944a1 — added /howto/gateway-extensions/ to the SEO meta-description list and the TOC howtoPages list in content.spec.ts, and added it (plus /howto/) to the link-crawl pagesToCrawl in links.spec.ts so broken links and missing meta/TOC on the new page now fail CI.
| | Manage readiness with workers | [Readiness Patterns](/howto/readiness) | | ||
| | Set up local dev with Docker | [Local Development](/howto/local-dev) | | ||
| | Add JWT / API key auth | [Authentication](/howto/auth) | | ||
| | Add custom HTTP marshalers or middleware | [HTTP Gateway Extensions](/howto/gateway-extensions) | |
There was a problem hiding this comment.
Addressed in f5944a1 — /howto/ is now in pagesToCrawl, so a typo in this row's href would surface as a broken link in CI.
- gateway-extensions.md: fix 'register per-route middleware' wording in the Overview to 'register gateway middleware', matching the recipe heading downstream. - gateway-extensions.md: rewrite the error-envelope warning callout. Only runtime.JSONPb and runtime.JSONBuiltin accept arbitrary Go values; the MessagePack recipe earlier on the page type-asserts proto.Message and would also reject map[string]any, so listing it alongside the JSON marshalers was wrong. - tests/links.spec.ts: add /howto/ and /howto/gateway-extensions/ to pagesToCrawl so a typo in the index entry or the new page's outgoing links is caught by the link-crawl suite. - tests/content.spec.ts: add /howto/gateway-extensions/ to the meta- description SEO list and the howtoPages list for the TOC test.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@howto/gateway-extensions.md`:
- Around line 58-112: The MessagePack marshaler (Marshaler.Marshal and
Marshaler.Unmarshal used with ContentType "application/msgpack") converts
protojson into a generic any via encoding/json which decodes numbers to float64
and can lose precision for large int64/uint64; add a visible warning callout
immediately after the curl/Content-Type paragraph (and the corresponding
secondary location mentioned in the review) explaining that decoding into
any/interface{} with encoding/json may convert integers to float64 and thus lose
precision for values > 2^53-1, and advise readers to avoid relying on this
bridge for large integer fields or to use a custom encoder/alternative approach.
- Around line 262-265: Reword the consecutive bullets under the "When to reach
for these hooks" list to avoid repeating "You need ..." by editing one of the
items (for example, change "You want the defaults of `runtime.JSONPb`
adjusted..." to "Adjust the defaults of `runtime.JSONPb` (field naming,
empty-value emission, indentation)" or similar); update any adjacent bullet that
starts with "You need ..." so the list reads more varied while preserving the
original meaning and examples (`msgpack, CBOR, YAML, vendor-specific binary`,
`raw-body access, file uploads, response streaming wrappers, request size
limits`, and the `runtime.JSONPb`/error envelope mentions).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: e20c1e78-255e-4cd5-8c6e-38f3a357a42e
📒 Files selected for processing (3)
howto/gateway-extensions.mdtests/content.spec.tstests/links.spec.ts
✅ Files skipped from review due to trivial changes (2)
- tests/links.spec.ts
- tests/content.spec.ts
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- gateway-extensions.md: add a precision-loss warning to the MessagePack recipe. The protojson-encoding/json-msgpack bridge decodes JSON numbers into 'any' as float64; int64/uint64 values greater than 2^53-1 lose precision through the round-trip. Point callers at a protoreflect-direct encoder for those fields. - gateway-extensions.md: tighten the JSONPb intro to acknowledge that runtime.MIMEWildcard serves both inbound (Content-Type) and outbound (Accept) sides, and update the follow-up note to mirror that on the override case. - gateway-extensions.md: rephrase the 'When to reach for these hooks' bullets so we don't have three consecutive 'You need …' bullets, and broaden the interceptors mental-model line to cover both server- and client-side interceptors (retries are a client concern). - tests/links.spec.ts: extend pagesWithAnchors with the #recipe-gateway-middleware fragment so the new in-page anchor link is verified. - tests/content.spec.ts: add /howto/local-dev/ to both pagesWithDescriptions (SEO) and the TOC howtoPages list. The page was already linked from howto/index.md and the navigation smoke list but was missing from the SEO and TOC suites.
Summary
howto/gateway-extensions.mdcovering core'sRegisterServeMuxOptionandRegisterHTTPMarshalerhooks. Includes an ordering-rules table (last-write-wins vs additive options) and four worked recipes: MessagePack marshaler viashamaton/msgpack+ protojson bridge, defaultJSONPbtuning viaruntime.MIMEWildcard, request-size middleware viaWithMiddlewares, and a vendor error envelope viaWithErrorHandler.howto/index.md— new row linking to the page.config-reference.md—DISABLE_ZSTD_COMPRESSIONandPREFER_ZSTDrows documenting the new core flags.tests/navigation.spec.ts—/howto/gateway-extensions/added to the PlaywrighthowtoPageslist so CI asserts the page loads.Depends on
go-coldbrew/core#88. The page references
core.RegisterHTTPMarshaler/core.RegisterServeMuxOption, which land in that PR. Safe to merge after core PR 88 is released; merging earlier just means the snippets reference an unreleased API for a window.Test plan
layout,title,parent,nav_order,description120–160 chars).npx playwright test --listparses the updated spec and includes the new/howto/gateway-extensions/test case.Out of scope
cb-mainsubmodule pointer — handled in a follow-upchore: sync submodulesafter both this PR and the core release land.Summary by CodeRabbit
New Features
Documentation
Tests